﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Coevery.AppFramework.MetadataServiceReference;
using Coevery.Win.DetailViewModule;
using Coevery.AppFramework.WinForms.Extensions;
using Coevery.AppFramework.Extensions;
using Coevery.AppFramework.WinForms.Views;
using Coevery.Win.InmuebleModule.Detail;
using DevExpress.XtraMap;
using System.Net.Http;
using System.Web;
using System.Net.Http.Formatting;

// ShowMap(); <-- Se comenta para que no enlentezca durante el debug 

namespace Coevery.Win.InmuebleModule.Detail
{
    public partial class InmuebleDetailView : DetailView, IInmuebleDetailView
    {

        private string ccaa;
        private string prov;
        private string municipio;
        private string numero;
        private string tipovia;
        private string via;
        private string cp;
        private string latitude;
        private string longitude;
        private bool shown;

        ReadOnlyCollection<OptionSet> hOptionSetList;
        Entity entity;

        private void initializeAddress(){
            ccaa = "";
            prov = "";
            municipio = "";
            numero = "";
            tipovia = "";
            via = "";
            cp ="";
            latitude = "";
            longitude = "";

        }

        public InmuebleDetailView()
        {
            initializeAddress();
            InitializeComponent();
        }

        public class BingLocationResult
        {
            public string authenticationResultCode { get; set; }
            public string brandLogoUri { get; set; }
            public string copyright { get; set; }
            public Locations[] resourceSets { get; set; }
            public int statusCode { get; set; }
            public string statusDescription { get; set; }
            public string traceId { get; set; }
        }

        public class Locations
        {
            public int estimatedTotal { get; set; }
            public Location[] resources { get; set; }
        }

        public class Location
        {
            public string __type { get; set; }
            public float[] bbox { get; set; }
            public string name { get; set; }
            public Point point { get; set; }
            public Address address { get; set; }
            public string confidence { get; set; }
            public string entityType { get; set; }
            public Geocodepoint[] geocodePoints { get; set; }
            public string[] matchCodes { get; set; }
        }

        public class Point
        {
            public string type { get; set; }
            public float[] coordinates { get; set; }
        }

        public class Address
        {
            public string addressLine { get; set; }
            public string adminDistrict { get; set; }
            public string adminDistrict2 { get; set; }
            public string countryRegion { get; set; }
            public string formattedAddress { get; set; }
            public string locality { get; set; }
            public string postalCode { get; set; }
        }

        public class Geocodepoint
        {
            public string type { get; set; }
            public float[] coordinates { get; set; }
            public string calculationMethod { get; set; }
            public string[] usageTypes { get; set; }
        }
        public override void InitEditors(Entity entity, Coevery.AppFramework.WinForms.Messages.EntityDetailWorkingMode _workingMode)
        {
            
            base.InitEditors(entity, _workingMode);
            this.entity = entity;
            this.lookUpEdit1.BindPickList(entity); // Tipo Via
            this.lookUpEdit2.BindPickList(entity); // TipoVivienda
            this.lookUpEdit6.BindPickList(entity); // Estado
            this.lookUpEdit4.BindPickList(entity); // AnioConstruccion
            this.lookUpEdit5.BindPickList(entity); // AnioReforma

            if (_workingMode == AppFramework.WinForms.Messages.EntityDetailWorkingMode.Add)
            {
                this.comunidadautonoma.BindPickList(entity); // Comunidad Autonoma
                this.provincia.BindPickList(entity, new Guid("00000000-0000-0000-0000-000000000000")); //Prov
                this.lookUpEdit3.BindPickList(entity, new Guid("00000000-0000-0000-0000-000000000000")); // Municipio
            }
            else // View and Edit
            {
                this.comunidadautonoma.BindPickList(entity); // Comunidad Autonoma
                this.provincia.BindPickList(entity); // Provincia
                this.lookUpEdit3.BindPickList(entity); // Municipio
            }

        }

        public override void InitHOptionSets(ReadOnlyCollection<OptionSet> list)
        {
            hOptionSetList = list;
            base.InitHOptionSets(list);
            
            //this.comunidadautonoma.BindPickList(list, null);
            //this.provincia.BindPickList(list, new Guid("00000000-0000-0000-0000-000000000000")); //Prov
            //this.lookUpEdit3.BindPickList(entity, new Guid("00000000-0000-0000-0000-000000000000")); // Municipio
            
        }

        public override void InitValidation()
        {
            SetValidationRule(lookUpEdit3, ValidationRules.IsNotBlankRule(this.lookUpEdit3.Text));
            SetValidationRule(lookUpEdit1, ValidationRules.IsNotBlankRule(this.lookUpEdit3.Text));
            SetValidationRule(textEdit2, ValidationRules.IsNotBlankRule(this.textEdit2.Text));
            SetValidationRule(textEdit3, ValidationRules.IsNotBlankRule(this.textEdit3.Text));
            //SetValidationRule(InmuebleNumberTextEdit, ValidationRules.IsNotBlankRule(ItemForInmuebleNumber.Text));
        }


        private void lookUpEdit2_EditValueChanged(object sender, EventArgs e)
        {

            if (this.comunidadautonoma.ItemIndex == -1)
                this.comunidadautonoma.ItemIndex = 0;
            this.provincia.BindPickList(this.hOptionSetList,
                                        (Guid)((List<LookupListItem<int?>>)this.comunidadautonoma.Properties.DataSource)[this.comunidadautonoma.ItemIndex].PickListValueID);
            this.provincia.ItemIndex = 0;
            
            ccaa = this.comunidadautonoma.Text;
            ShowMap();

        }

        private void lookUpEdit4_EditValueChanged(object sender, EventArgs e)
        {

            if (this.provincia.ItemIndex == -1)
                this.provincia.ItemIndex = 0;
            this.lookUpEdit3.BindPickList(this.entity,
                                        (Guid)((List<LookupListItem<int?>>)this.provincia.Properties.DataSource)[this.provincia.ItemIndex].PickListValueID);
            this.lookUpEdit3.ItemIndex = 0;

            prov = this.provincia.Text;
            ShowMap();

        }


        #region debuggingstuff
        private void lookUpEdit3_InvalidValue(object sender, DevExpress.XtraEditors.Controls.InvalidValueExceptionEventArgs e)
        {
            /*
            e.ExceptionMode = DevExpress.XtraEditors.Controls.ExceptionMode.NoAction;
            var ind = this.lookUpEdit3.ItemIndex;
            var text = this.lookUpEdit3.Text;
            Console.WriteLine(ind+text);

            //var ind = this.lookUpEdit3.ItemIndex;
            if (ind != -1)
            {
                int editvalue = (int)lookUpEdit3.Properties.GetDataSourceValue("Value", ind);
                this.lookUpEdit3.EditValue = editvalue;
            }
            */
        }

        private void lookUpEdit3_EditValueChanging(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e)
        {

        }
        #endregion

        private void EntityBindingSource_CurrentChanged(object sender, EventArgs e)
        {

        }

        private void textEdit3_EditValueChanged(object sender, EventArgs e)
        {
            //numero
            numero = this.textEdit3.Text;
            ShowMap();
        }

        private void textEdit8_EditValueChanged(object sender, EventArgs e)
        {
            // CP
            cp = this.textEdit8.Text;
            ShowMap();
        }



        private void lookUpEdit1_EditValueChanged(object sender, EventArgs e)
        {
            //Tipo Via
            tipovia = this.lookUpEdit1.Text;
            ShowMap();
        }

        private void textEdit2_EditValueChanged(object sender, EventArgs e)
        {
            // Nombre Via
            via = this.textEdit2.Text;
            ShowMap();
        }

        private void lookUpEdit3_EditValueChanged(object sender, EventArgs e)
        {
            // Municipio
            municipio = this.lookUpEdit3.Text; 
            ShowMap();
        }

        private async void ShowMap()
        {
            //if (shown) return;
            if (false) return; // True para debuggear

            try
            {
                if (/*false &&*/ latitude != "" && longitude != "" && !shown) // CODIGO REPLICADO, NO FUNCIONA. REVISAR
                {
                    shown = true;

                    string uri = "http://dev.virtualearth.net/REST/v1/Locations/{0}?&key=Ag8BasusptLtUJoWha0CxRNnV0a28Vn39QOsqnGAmnopvdg6paZfeyMOj9Cobumu";
                    string requestUri = string.Format(uri, HttpUtility.UrlEncode(latitude + "," + longitude));

                    HttpClient client = new HttpClient();
                    var response = await client.GetAsync(requestUri);
                    //response.EnsureSuccessStatusCode();
                    var result = await response.Content.ReadAsAsync<BingLocationResult>();
                    // and now the processing of the result...

                    MapPushpin pin = new MapPushpin();
                    double lat = result.resourceSets[0].resources[0].geocodePoints[0].coordinates[0];
                    double lon = result.resourceSets[0].resources[0].geocodePoints[0].coordinates[1];
                    pin.Location = new GeoPoint(lat, lon);
                    pin.Visible = true;

                    ImageTilesLayer itemsLayer = (ImageTilesLayer)this.mapControl1.Layers[0];
                    VectorItemsLayer vItemsLayer = new VectorItemsLayer();
                    this.mapControl1.Layers.Add(vItemsLayer);
                    vItemsLayer.Items.Clear();
                    vItemsLayer.Items.Add(pin);

                    MapPoint point = new MapPoint(vItemsLayer.GeoToScreenPoint(pin.Location).X,
                    vItemsLayer.GeoToScreenPoint(pin.Location).Y);

                    mapControl1.Zoom(17, point);
                }

                if (!shown && ccaa != "" && prov != "" && municipio != "" && cp != "" && tipovia != "" && via != "" && numero != "")
                {
                    shown = true;

                    string uri = "http://dev.virtualearth.net/REST/v1/Locations?countryRegion={0}&adminDistrict={1}&locality={2}&postalCode={3}&addressLine={4}&includeNeighborhood=false&maxResults=1&key=Ag8BasusptLtUJoWha0CxRNnV0a28Vn39QOsqnGAmnopvdg6paZfeyMOj9Cobumu";

                    string requestUri = string.Format(uri,
                        HttpUtility.UrlEncode("España"),                    // Pais
                        HttpUtility.UrlEncode(this.comunidadautonoma.Text), // CCAA
                        HttpUtility.UrlEncode(this.lookUpEdit3.Text),       // Provincia
                        HttpUtility.UrlEncode(this.textEdit8.Text),         // Municipio
                        HttpUtility.UrlEncode(this.textEdit3.Text + " " +   // Numero
                                              this.lookUpEdit1.Text +  " " +// Tipo Via
                                              this.textEdit2.Text)          // Nombre Via
                        );

                    HttpClient client = new HttpClient();
                    var response = await client.GetAsync(requestUri);
                    //response.EnsureSuccessStatusCode();
                    var result = await response.Content.ReadAsAsync<BingLocationResult>();
                    // and now the processing of the result...

                    MapPushpin pin = new MapPushpin();
                    double lat = result.resourceSets[0].resources[0].geocodePoints[0].coordinates[0];
                    if (this.textEdit6.Text == null || this.textEdit6.Text == "")
                        this.textEdit6.Text = lat.ToString();

                    double lon = result.resourceSets[0].resources[0].geocodePoints[0].coordinates[1];
                    if (this.textEdit7.Text == null || this.textEdit7.Text == "")
                        this.textEdit7.Text = lon.ToString();
                    pin.Location = new GeoPoint(lat, lon);
                    pin.Visible = true;

                    ImageTilesLayer itemsLayer = (ImageTilesLayer)this.mapControl1.Layers[0];
                    VectorItemsLayer vItemsLayer = new VectorItemsLayer();
                    this.mapControl1.Layers.Add(vItemsLayer);
                    vItemsLayer.Items.Clear();
                    vItemsLayer.Items.Add(pin);

                    MapPoint point = new MapPoint(vItemsLayer.GeoToScreenPoint(pin.Location).X,
                    vItemsLayer.GeoToScreenPoint(pin.Location).Y);

                    mapControl1.Zoom(17, point);
                }
            }
            catch (Exception e) { 
                // Handle exception
            }
        }

        private void checkEdit2_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void checkEdit4_CheckedChanged(object sender, EventArgs e)
        {
            //Checked Cocina
            Console.WriteLine("Test");
        }

        private void checkEdit4_EditValueChanged(object sender, EventArgs e)
        {
            //Checked Cocina
            Console.WriteLine("Test");
        }

        private void textEdit6_EditValueChanged(object sender, EventArgs e)
        {
            // Latitud
            latitude = this.textEdit6.Text;

        }

        private void textEdit7_EditValueChanged(object sender, EventArgs e)
        {
            // Longitud
            longitude = this.textEdit7.Text;
        }
    }
}
